home *** CD-ROM | disk | FTP | other *** search
/ PC Plus SuperCD (UK) 1998 August / PC Plus SuperCD 50b Issue 142 (CD142b) (August 1998).iso / essent / FIXES / CSeries.exe / issue101 / CPROG19.CPP < prev   
Encoding:
C/C++ Source or Header  |  1995-02-28  |  6.6 KB  |  164 lines

  1. // CPROG19.CPP - an OOP version of last month's CPROG15.CPP
  2. //               It creates and uses a file directory object
  3.  
  4.  
  5. #include <stdlib.h>
  6. #include <iostream.h>    // Needed for stream-related features such as cout and <<
  7. #include <iomanip.h>    // Defines manipulators for cout - such as setw() to set the field width
  8. #include <dos.h>
  9. #include <dir.h>
  10. #include <string.h>
  11.  
  12.  
  13.  
  14. //////////////////////////////////////////////////////////////////////////////
  15. class dirlist {    // Object to create, store and provide access to linked list
  16.         // of filenames.
  17.  
  18. struct filerecord {                   // Now private data within
  19.         char filename[13];             // the dirlist object. Only
  20.         char attribute;                // member functions can get
  21.         struct filerecord *previous;   // at the pointers *firstrec
  22.         struct filerecord *next;       // and *current, and therefore
  23.         } *firstrec, *current;         // any structures they point to
  24.  
  25.     void makeattstring(char attribute);    // A member function to turn
  26.                         // an attribute into a string.
  27.                         // It is private, so only
  28.                         // other member functions may
  29.                         // use it.
  30. public:
  31.     dirlist(char *pathname);                // Constructor builds the list
  32.     ~dirlist(void);                // Destructor destroys list
  33.  
  34.     void setrec(int recnum);                // Sets the number of the
  35.                         // record we're interested in
  36.     char filename[13], attstring[7];        // Character arrays to be
  37.                         // filled in with data from
  38.                         // current record by setrec()
  39. };
  40. //----------------------------------------------------------------------------
  41. dirlist::dirlist(char *pathname)    // The constructor builds the list
  42. {                // The code is pasted from CPROG15.CPP with
  43.                 // a couple of minor mods such as the list
  44.                 // and its pointers being part of the object
  45.                 // and the comments removed
  46. struct ffblk filedetails;
  47. struct filerecord *temp;
  48.  
  49.     findfirst(pathname, &filedetails, FA_RDONLY+FA_HIDDEN+FA_SYSTEM+FA_LABEL+FA_DIREC+FA_ARCH);
  50.     temp=firstrec=0;
  51.     do {
  52.         if( ! (current=new filerecord) )
  53.             {
  54.             cout << "Oh dear, we're clean out of spare bytes!\n";
  55.             exit(0);
  56.             }
  57.  
  58.         if( firstrec == 0 )
  59.             firstrec=current;
  60.         strcpy( current->filename, filedetails.ff_name );
  61.         current->attribute = filedetails.ff_attrib;
  62.         current->previous=temp;
  63.         if ( temp )
  64.             temp->next=current;
  65.         temp=current;
  66.     } while( ! findnext(&filedetails) );
  67.     current->next=0;
  68.  
  69.     setrec(0);  // Make sure the public variables are intialised
  70. }
  71.  
  72. //----------------------------------------------------------------------------
  73. dirlist::~dirlist(void)    // Destructor releases all the memory allocated
  74.             // to the linked list by the constructor using
  75.             // DELETE. It threads forward along the NEXT pointers
  76.             // deleting the previous strucutre in list.
  77. {
  78.     current=firstrec;
  79.     do {
  80.         current=current->next;
  81.         delete current->previous;
  82.         } while( current->next );
  83.     delete current;    // At end of list delete current (=final) structure.
  84. }
  85. //----------------------------------------------------------------------------
  86. void dirlist::setrec(int recnum) // Makes current record recnum-th in list
  87.                 // and copies details to public char
  88.                 // arrays attstring[] and filename[]
  89.                 // Index for recnum begins at 0
  90.                 // This is a very slow method - in a
  91.                 // live program a faster technique would
  92.                 // be used.
  93. {
  94.     for(current=firstrec; current->next && recnum; recnum--)
  95.         current=current->next; // Step forward as long as there's
  96.                     // a structure to step forward to
  97.                     // and recnum hasn't been decremented
  98.                     // to zero.
  99.  
  100.     if( recnum )    // If recnum was bigger than the list, and therefore
  101.             // hasn't been decremented to zero...
  102.         attstring[0]=filename[0]='\0';    // Signify error by zeroing
  103.                           // filename and attribute
  104.     else
  105.         {
  106.         makeattstring(current->attribute);   // else update them with
  107.         strcpy(filename, current->filename); // details from current
  108.         }                                    // record
  109. }
  110. //----------------------------------------------------------------------------
  111. void dirlist::makeattstring(char attribute)    // Converts attribute byte
  112. {                                               // to a user-friendly string
  113. static char attlets[]= "ADLSHR";                // - another paste from
  114. int i;                                          // CPROG15.CPP, with comments
  115.                         // removed and attstring[]
  116.     for(i=5; i>=0; i--)                     // placed in object's public
  117.         {                               // data area.
  118.         attstring[i]= (attribute & 1 ) ? attlets[i] : '-';
  119.         attribute=attribute >> 1;
  120.         }
  121.     attstring[6]='\0';
  122. }
  123. //////////////////////////////////////////////////////////////////////////////
  124. void main(void)
  125. {
  126. int i;
  127. dirlist dir1("C:\\*.*"); // Create a dirlist object called dir1. Its
  128.             // constructor function expects a pathname
  129.             // for the directory to be read.
  130.     /* Print out the directory names. Knows when it has got to end of list
  131.     when the filename becomes a null string (ie '\0' at 1st char position */
  132.     for(i=0, dir1.setrec(0); dir1.filename[0]; i++ )
  133.         {
  134.         dir1.setrec(i);  // Set record to current value of i
  135.         cout << setw(12) << dir1.filename << '\t' << dir1.attstring << '\n';
  136.         }
  137. }
  138.  
  139. //////////////////////////////////////////////////////////////////////////////
  140. /* NOTES:
  141. 1: setw() is what is known as a manipulator. It is one of a series of
  142. functions which manipulate the format of data on its way to the output
  143. stream (cout) or coming from the input stream (cin). setw(12) is equivalent
  144. to %12s in a printf() call. The cout line is equivalent to:
  145.      printf("%12s\t%s\n", dir1.filename, dir1.attstring);
  146. Manipulators are not well covered in the help system. Read the file iomanip.h
  147. for more information, though this is one area where you really need
  148. a manual.
  149. 2: Improvments to the dirlist class would be...
  150. - to get it to store the pathanme so that if multiple instamces are created
  151.   for different directories, it is easy to see what's what.
  152. - a faster record location algorithm for setrec(). Two ideas for this are:
  153.     - not to use a linked list but an array of structures. This would require
  154.        the number of filenames to be determined first, then a block of
  155.        memory large enough for an array to be allocated before reading the
  156.        names
  157.     - to build a list of pointers to every 16th record, and use the nearest
  158.       index as a startign point for threading
  159. - functions to step backwards or forwards n records from the current position
  160. - a fucntion to sort records according to one of a number of criteria, like
  161.   the sort options in File Manager.
  162. - the ability to filter out certain types of file by feeding the constructor
  163.   allowable file attributes.
  164. */